#coding=utf-8
__author__ = 'Meteor'
'''
发送请求
'''
import  requests
import setings
import json
from api.assertion import assert_status_code,assert_json_eq
from common.extract import exrtact
from common.log import logger

class Resq:
    def __init__(self):
        # 定义session来保持会话
        self.session = requests.Session()

        # 定义接口的默认请求头
        self.headers = setings.headers
        # 定义默认json请求数据
        self.json = {}

        # 定义默认表单数据
        self.data = {}

        # 定义一个默认的token
        self.token = setings.TOKEN

        # 初始化params参数
        self.params = {}

        # 定义一个默认的响应
        self.__response = None

        # 每个接口的请求都有断言，默认设置为空
        self.assertin = {}

    def get(self,url,params,headers=''):
        # 将服务器地址与接口地址拼接，拼接出接口的完整地址
        url = setings.URL + url
        # 判断是否有设置自定义headers，如果有，则更新headers
        if headers:

            self.headers.update(headers)
        # 判断当前接口的params参数是否为空
        if not self.params:
            self.params = params


        # 发送get请求，并修改response的值。self.response是一个Response的对象
        self.__response = self.session.get(url=url,params=self.params,headers=self.headers)
        logger.info('send get request : url[%s],params[%s],header[%s]' %(url,str(self.params),str(self.headers)))
        logger.info('test response : %s' %self.response.text)

    def post(self,url,data,headers='',json=''):
        # 拼接接口地址
        url = setings.URL + url
        # 处理请求时的请求头
        if headers:
            self.headers = headers


        # 如果是json格式，传入json数据
        if json:
            self.json = json

        # 如果是（form表单提交）data

        if not self.data:
            # 判断如果self.data中有数据，那么直接取self.data，否则取yaml文件中的数据
            self.data = data

        # 修改response的值（self.response始终记录最后一次请求的响应）
        self.__response = self.session.post(url=url,data=self.data,headers = self.headers,json=self.json)
        logger.info('send post reqquest:url[%s],data[%s],header[%s],json[%s]' %(url,str(self.data),str(self.headers),str(self.json)))
        self.data = {}

    @property
    def response(self):
        # 对外提供了一个获取响应方法
        return self.__response


    # d定义一个修改data数据的方法
    # @property
    # def data(self):
    #     return  self.data
    #
    # @data.setter
    # def data(self,info):
    #     self.data = info


    def get_token(self):
        # 获取token方法
        self.token = json.loads(self.__response.text).get('data').get('token')
        logger.info('get token:%s' %self.token)
        return self.token


    def assert_exprt(self,api):
        '''
        
        :param api: 
        {'url': '/sys/login', 'data': {'username': '小皮在此', 'password': 123, 'role': 'member'}, 'metch': 'post', 'extract': {'token': '$.data.token'}, 'assert': {'status_code': 200, '$.message': '登录成功'}}
        data:是post请求中参数
        extract：表示需要提取数据
        assert：表示要断言的内容
        
        :return: 
        '''
        # 判断是否做自定义断言设置
        if self.assertin:
            print(self.assertin)
            for x,y in self.assertin.items():
                assert_json_eq(self.response, x, y)
            return


        # 判断yam文件中的接口是否设置了断言
        if api.get('assert'):

            for x,y in api.get('assert').items():
                # 判断是否为断言响应状态码
                if x == 'status_code':
                    logger.info('assert:assert_status_code:%s' %y)
                    try:
                        assert_status_code(self.response,y)
                    except AssertionError:
                        logger.error('断言失败，预期结果是%s ,实际结果是：%s' %(y,self.response.text))
                        raise AssertionError


                # 判断是否为json断言
                if x.startswith('$'):
                    logger.info('assert:assert_json_eq: {%s:%s}' %(str(x),str(y)))
                    try:
                        assert_json_eq(self.response,x,y)
                    except AssertionError:
                        logger.error('断言失败，预期结果是%s ,实际结果是：%s' %(y,self.response.text))
                        raise AssertionError

    def extract_exprt(self,api):
        # 判断接口中是否需要提取数据
        if api.get('extract'):
            # 响应结果中提取方法
            exrtact.extract_data(api, self.response)



if __name__ == '__main__':
    resq = Resq()
    # resq.post(url = '/sys/login',data={'username': '小皮在此', 'password': 123, 'role': 'member'})
    # print(resq.response.text)
    # resq.assertin ={'$.message':'登录成功'}
    # resq.assert_exprt({'a':'b'})

    # 调试api参数：
    api = {'url': '/sys/login', 'data': {'username': '小皮在此', 'password': 123, 'role': 'member'}, 'metch': 'post', 'extract': {'token': '$.data.token'}, 'assert': {'status_code': 200, '$.message': '登录成功'}}

    resq.post(url = api.get('url'),data=api.get('data'))
    resq.assert_exprt(api)

